//**************************************************
// include files
//**************************************************
`include "MAC_define.v"
`include "protocol_define.v"
`include "work_mode_define.v"

//**************************************************
// timescale
//**************************************************
`timescale 1ns/100ps


module Eth_1G_UDP_system (
    input               clk_in                      , // UDP system clock
    input               reset                       , // reset pin
    input   [11:0]      ram_dp_cfg_register         ,
    input   [9:0]       ram_2p_cfg_register         ,
    //----------------------------------------------
    // PHY interface
    //----------------------------------------------
    // reset "PHY"
    // output              phyrst_n                    , 

    // // RGMII receive channel
    // input               rgmii_rx_clk                ,
    // input               rgmii_rx_ctrl               ,
    // input   [3:0]       rgmii_rxd                   ,
    // // RGMII send channel
    // output              rgmii_tx_clk                ,
    // output              rgmii_tx_ctrl               ,
    // output  [3:0]       rgmii_txd                   ,
    output              mac_rx_rdy                  ,
    input   [31:0]      mac_rx_data                 ,
    input   [1:0]       mac_rx_mod                  ,
    input               mac_rx_sav                  ,
    input               mac_rx_val                  ,
    input               mac_rx_sop                  ,
    input               mac_rx_eop                  ,
    input   [10:0]      mac_rx_data_length          ,

    input               mac_tx_rdy                  ,
    output  [31:0]      mac_tx_data                 ,
    output  [1:0]       mac_tx_mod                  ,
    output              mac_tx_val                  ,
    output              mac_tx_sop                  ,
    output              mac_tx_eop                  ,

    //----------------------------------------------
    // AHB interface
    //----------------------------------------------
    input               NP_clk_312M              , 
    // output              AHB_312p5M_clk              ,
    output  [31:0]      AHB_haddr_m                 ,
    output  [31:0]      AHB_hwdata_m                ,
    output              AHB_hwrite_m                ,
    output  [2:0]       AHB_hsize_m                 ,
    output  [2:0]       AHB_hburst_m                ,
    output  [1:0]       AHB_htrans_m                ,
    output  [3:0]       AHB_hmaster_m               ,
    output              AHB_hnonsec_m               ,
    output              AHB_hexcl_m                 ,
    output              AHB_hmasterlock_m           ,
    output  [6:0]       AHB_hprot_m                 ,
    input   [31:0]      AHB_hrdata_m                ,
    input               AHB_hready_m                ,
    input               AHB_hresp_m         
) ;

//**************************************************
// signal declare
//**************************************************
    // wire                            ACTION_fifo_clk ;
    // wire                            NP_clk_312M ; // (only FPGA version)
    // rx channel async FIFO port A
    wire                            ACTION_wr_en    ;
    wire    [29:0]                  ACTION_wr_order ;
    wire    [33:0]                  ACTION_wr_addr  ;
    wire    [31:0]                  ACTION_wr_data  ;
    wire                            ACTION_wr_full  ;
    // rx channel async FIFO port B
    wire                            rx_rd_en        ;
    wire    [29:0]                  rx_rd_order     ;
    wire    [33:0]                  rx_rd_addr      ;
    wire    [31:0]                  rx_rd_data      ;
    wire                            rx_rd_empty     ;

    // tx channel async FIFO port A
    wire                            ACTION_rd_en    ;
    wire    [29:0]                  ACTION_rd_order ;
    wire    [33:0]                  ACTION_rd_addr  ;
    wire    [31:0]                  ACTION_rd_data  ;
    wire                            ACTION_rd_empty ;
    // tx channel async FIFO port B
    wire                            tx_wr_en        ;
    wire    [29:0]                  tx_wr_order     ;
    wire    [33:0]                  tx_wr_addr      ;
    wire    [31:0]                  tx_wr_data      ;
    wire                            tx_wr_full      ;
/*
//**************************************************
// 312.5MHz clock generator (only FPGA version)
//**************************************************
    wire    MMCM_locked ;
    wire    clk_100M_top_use ;

    // Instantiation of the MMCM primitive
	//    * Unused inputs are tied off
	//    * Unused outputs are labeled unused
    wire        clkout0;
	wire        clkout0b_unused;
	wire [15:0] do_unused;
	wire        drdy_unused;
	wire        psdone_unused;
	wire        clkfbout;
	wire        clkfboutb_unused;
	wire        clkfbstopped_unused;
	wire        clkinstopped_unused;

`ifdef FPGA_ZEDBOARD_MODE
	MMCME2_ADV #(
		.BANDWIDTH          	("OPTIMIZED"),	// Jitter programming (OPTIMIZED, HIGH, LOW)
		.CLKFBOUT_MULT_F      	(6.250),		// Multiply value for all CLKOUT (2.000-64.000).
		.CLKFBOUT_PHASE       	(0.000),		// Phase offset in degrees of CLKFB (-360.000-360.000).
		// CLKIN_PERIOD: Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).
		.CLKIN1_PERIOD        	(10.000),
		// CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for CLKOUT (1-128)
		.CLKOUT0_DIVIDE_F     	(2.000),  		// Divide amount for CLKOUT0 (1.000-128.000).
		// CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for CLKOUT outputs (0.01-0.99).
		.CLKOUT0_DUTY_CYCLE   	(0.500),
		// CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for CLKOUT outputs (-360.000-360.000).
		.CLKOUT0_PHASE        	(0.000),
		.COMPENSATION         	("ZHOLD"),
		.DIVCLK_DIVIDE        	(1),
		// REF_JITTER: Reference input jitter in UI (0.000-0.999).
		.REF_JITTER1          	(0.010) ,
		.STARTUP_WAIT         	("FALSE"),
		// USE_FINE_PS: Fine phase shift enable (TRUE/FALSE)
		.CLKFBOUT_USE_FINE_PS 	("FALSE"),
		.CLKOUT0_USE_FINE_PS  	("FALSE")
    ) inst_312M_clk_gen (
		// Clock Outputs: 1-bit (each) output: User configurable clock outputs
		.CLKOUT0             (clkout0),
		.CLKOUT0B            (clkout0b_unused),
		// DRP Ports: 16-bit (each) output: Dynamic reconfiguration ports
		.DO                  (do_unused),
  		.DRDY                (drdy_unused),
		// Dynamic Phase Shift Ports: 1-bit (each) output: Ports used for dynamic phase shifting of the outputs
		.PSDONE              (psdone_unused),
		// Feedback Clocks: 1-bit (each) output: Clock feedback ports
		.CLKFBOUT            (clkfbout),
		.CLKFBOUTB           (clkfboutb_unused),
		// Status Ports: 1-bit (each) output: MMCM status ports
  		.LOCKED              (MMCM_locked),
  		.CLKINSTOPPED        (clkinstopped_unused),
  		.CLKFBSTOPPED        (clkfbstopped_unused),
   		// Input clock control
  		.CLKIN1              (clk_100M_top_use),
  		.CLKIN2              (1'b0),
   		// Tied to always select the primary input clock
  		.CLKINSEL            (1'b1),
		.PWRDWN              (1'b0),
  		.RST                 (reset),
  		// DRP Ports: 7-bit (each) input: Dynamic reconfiguration ports
  		.DADDR               (7'h0),
  		.DCLK                (1'b0),
  		.DEN                 (1'b0),
  		.DI                  (16'h0),
  		.DWE                 (1'b0),
  		// Ports for dynamic phase shift
  		.PSCLK               (1'b0),
  		.PSEN                (1'b0),
  		.PSINCDEC            (1'b0),
		// Feedback Clocks: 1-bit (each) input: Clock feedback ports
		.CLKFBIN             (clkfbout)
	);
`elsif FPGA_VCU13PBOARD_MODE
    wire CDDCDONE_unused ;
    wire CDDCREQ_unused ;
    MMCME3_ADV #(
        .BANDWIDTH              ("OPTIMIZED"),      // Jitter programming (HIGH, LOW, OPTIMIZED)
        .CLKFBOUT_MULT_F        (12.500),           // Multiply value for all CLKOUT (2.000-64.000)
        .CLKFBOUT_PHASE         (0.000),            // Phase offset in degrees of CLKFB (-360.000-360.000)
        // CLKIN_PERIOD: Input clock period in ns units, ps resolution (i.e. 33.333 is 30 MHz).
        .CLKIN1_PERIOD          (10.000),
        // CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for CLKOUT (1-128)
        .CLKOUT0_DIVIDE_F       (4.000),            // Divide amount for CLKOUT0 (1.000-128.000)
        // CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for CLKOUT outputs (0.001-0.999).
        .CLKOUT0_DUTY_CYCLE     (0.500),
        // CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for CLKOUT outputs (-360.000-360.000).
        .CLKOUT0_PHASE          (0.0),
        .COMPENSATION           ("ZHOLD"),          // AUTO, BUF_IN, EXTERNAL, INTERNAL, ZHOLD
        .DIVCLK_DIVIDE          (1),                // Master division value (1-106)
        // Programmable Inversion Attributes: Specifies built-in programmable inversion on specific pins
        .IS_CLKFBIN_INVERTED    (1'b0),             // Optional inversion for CLKFBIN
        .IS_CLKIN1_INVERTED     (1'b0),             // Optional inversion for CLKIN1
        .IS_CLKIN2_INVERTED     (1'b0),             // Optional inversion for CLKIN2
        .IS_CLKINSEL_INVERTED   (1'b0),             // Optional inversion for CLKINSEL
        .IS_PSEN_INVERTED       (1'b0),             // Optional inversion for PSEN
        .IS_PSINCDEC_INVERTED   (1'b0),             // Optional inversion for PSINCDEC
        .IS_PWRDWN_INVERTED     (1'b0),             // Optional inversion for PWRDWN
        .IS_RST_INVERTED        (1'b0),             // Optional inversion for RST
        // REF_JITTER: Reference input jitter in UI (0.000-0.999).
        .REF_JITTER1            (0.010),
        .REF_JITTER2            (0.010),
        .STARTUP_WAIT           ("FALSE"),          // Delays DONE until MMCM is locked (FALSE, TRUE)
        // Spread Spectrum: Spread Spectrum Attributes
        .SS_EN                  ("FALSE"),          // Enables spread spectrum (FALSE, TRUE)
        .SS_MODE                ("CENTER_HIGH"),    // CENTER_HIGH, CENTER_LOW, DOWN_HIGH, DOWN_LOW
        .SS_MOD_PERIOD          (10000),            // Spread spectrum modulation period (ns) (4000-40000)
        // USE_FINE_PS: Fine phase shift enable (TRUE/FALSE)
        .CLKFBOUT_USE_FINE_PS   ("FALSE"),
        .CLKOUT0_USE_FINE_PS    ("FALSE")
    )
    inst_312M_clk_gen (
        // Clock Outputs outputs: User configurable clock outputs
        .CLKOUT0                (clkout0),          // 1-bit output: CLKOUT0
        .CLKOUT0B               (clkout0b_unused),  // 1-bit output: Inverted CLKOUT0
        // DRP Ports outputs: Dynamic reconfiguration ports
        .DO                     (do_unused),        // 16-bit output: DRP data
        .DRDY                   (drdy_unused),      // 1-bit output: DRP ready
        // Dynamic Phase Shift Ports outputs: Ports used for dynamic phase shifting of the outputs
        .PSDONE                 (psdone_unused),    // 1-bit output: Phase shift done
        // Feedback outputs: Clock feedback ports
        .CLKFBOUT               (clkfbout),         // 1-bit output: Feedback clock
        .CLKFBOUTB              (clkfboutb_unused), // 1-bit output: Inverted CLKFBOUT
        // Status Ports outputs: MMCM status ports
        .CDDCDONE               (CDDCDONE_unused),  // 1-bit output: Clock dynamic divide done
        .CLKFBSTOPPED           (clkfbstopped_unused),  // 1-bit output: Feedback clock stopped
        .CLKINSTOPPED           (clkinstopped_unused),  // 1-bit output: Input clock stopped
        .LOCKED                 (MMCM_locked),      // 1-bit output: LOCK
        .CDDCREQ                (CDDCREQ_unused),   // 1-bit input: Request to dynamic divide clock
        // Clock Inputs inputs: Clock inputs
        .CLKIN1                 (clk_100M_top_use), // 1-bit input: Primary clock
        .CLKIN2                 (1'b0),             // 1-bit input: Secondary clock
        // Control Ports inputs: MMCM control ports
        .CLKINSEL               (1'b1),             // 1-bit input: Clock select, High=CLKIN1 Low=CLKIN2
        .PWRDWN                 (1'b0),             // 1-bit input: Power-down
        .RST                    (reset),            // 1-bit input: Reset
        // DRP Ports inputs: Dynamic reconfiguration ports
        .DADDR                  (7'h0),             // 7-bit input: DRP address
        .DCLK                   (1'b0),             // 1-bit input: DRP clock
        .DEN                    (1'b0),             // 1-bit input: DRP enable
        .DI                     (16'h0),            // 16-bit input: DRP data
        .DWE                    (1'b0),             // 1-bit input: DRP write enable
        // Dynamic Phase Shift Ports inputs: Ports used for dynamic phase shifting of the outputs
        .PSCLK                  (1'b0),             // 1-bit input: Phase shift clock
        .PSEN                   (1'b0),             // 1-bit input: Phase shift enable
        .PSINCDEC               (1'b0),             // 1-bit input: Phase shift increment/decrement
        // Feedback inputs: Clock feedback ports
        .CLKFBIN                (clkfbout)          // 1-bit input: Feedback clock
    );
`endif

	BUFG clkout0_buf (
		.O   (NP_clk_312M),
		.I   (clkout0)
	);
    assign AHB_312p5M_clk = NP_clk_312M ;
*/
//**************************************************
// protocol deal system 
//**************************************************
    Eth_1G_udp_top  inst_ETH_system (

        .clk_in                     (clk_in             ) ,
        .reset                      (reset              ) ,
        .ram_2p_cfg_register        (ram_2p_cfg_register) ,
        // PHY port 
        // .phyrst_n                   (phyrst_n           ) ,

        // .rgmii_rx_clk               (rgmii_rx_clk       ) ,
        // .rgmii_rx_ctrl              (rgmii_rx_ctrl      ) ,
        // .rgmii_rxd                  (rgmii_rxd          ) ,
        // .rgmii_tx_clk               (rgmii_tx_clk       ) ,
        // .rgmii_tx_ctrl              (rgmii_tx_ctrl      ) ,
        // .rgmii_txd                  (rgmii_txd          ) ,
        .mac_rx_rdy                 (mac_rx_rdy         ),
        .mac_rx_data                (mac_rx_data        ),
        .mac_rx_mod                 (mac_rx_mod         ),
        .mac_rx_sav                 (mac_rx_sav         ),
        .mac_rx_val                 (mac_rx_val         ),
        .mac_rx_sop                 (mac_rx_sop         ),
        .mac_rx_eop                 (mac_rx_eop         ),
        .mac_rx_data_length         (mac_rx_data_length ),

        .mac_tx_rdy                 (mac_tx_rdy         ),
        .mac_tx_data                (mac_tx_data        ),
        .mac_tx_mod                 (mac_tx_mod         ),
        .mac_tx_val                 (mac_tx_val         ),
        .mac_tx_sop                 (mac_tx_sop         ),
        .mac_tx_eop                 (mac_tx_eop         ),


        // NP port
        // .clk_100M_top_use           (clk_100M_top_use   ) ,
        // .ACTION_fifo_clk            (ACTION_fifo_clk    ) ,

        .ACTION_wr_en               (ACTION_wr_en       ) ,
        .ACTION_wr_order            (ACTION_wr_order    ) ,
        .ACTION_wr_addr             (ACTION_wr_addr     ) ,
        .ACTION_wr_data             (ACTION_wr_data     ) ,

        .ACTION_rd_en               (ACTION_rd_en       ) ,
        .ACTION_rd_order            (ACTION_rd_order    ) ,
        .ACTION_rd_addr             (ACTION_rd_addr     ) ,
        .ACTION_rd_data             (ACTION_rd_data     ) ,
        .ACTION_rd_empty            (ACTION_rd_empty    ) ,

        .NP_MAC_address             (`NP_MAC_ADDR       ) ,
        .NP_IP_address              (`NP_IP_ADDR        ) ,
        .NP_port_address            (`NP_PORT_ADDR      ) ,
        .NP_action_addition         (`PROTOCOL_ACTION_ADDITION)
    ) ;



    assemble_async_fifo inst_async_fifos(
        .portA_clk                  (clk_in             ) ,
        .portB_clk                  (NP_clk_312M        ) ,
        .rst                        (reset              ) ,
        .ram_dp_cfg_register        (ram_dp_cfg_register) ,

        // rx channel port A
        .ACTION_wr_en               (ACTION_wr_en       ) ,
        .ACTION_wr_order            (ACTION_wr_order    ) ,
        .ACTION_wr_addr             (ACTION_wr_addr     ) ,
        .ACTION_wr_data             (ACTION_wr_data     ) ,
        .rx_wr_full                 (ACTION_wr_full     ) ,
        // rx channel port B
        .rx_rd_en                   (rx_rd_en           ) ,
        .rx_rd_order                (rx_rd_order        ) ,
        .rx_rd_addr                 (rx_rd_addr         ) ,
        .rx_rd_data                 (rx_rd_data         ) ,
        .rx_rd_empty                (rx_rd_empty        ) ,

        // tx channel port A
        .ACTION_rd_en               (ACTION_rd_en       ) ,
        .ACTION_rd_order            (ACTION_rd_order    ) ,
        .ACTION_rd_addr             (ACTION_rd_addr     ) ,
        .ACTION_rd_data             (ACTION_rd_data     ) ,
        .ACTION_rd_empty            (ACTION_rd_empty    ) ,
        // tx channel port B
        .tx_wr_en                   (tx_wr_en           ) ,
        .tx_wr_order                (tx_wr_order        ) ,
        .tx_wr_addr                 (tx_wr_addr         ) ,
        .tx_wr_data                 (tx_wr_data         ) ,
        .tx_wr_full                 (tx_wr_full         ) 
    ) ;



    AHB_deal #(
        .ORDER_WIDTH                (`PROTOCOL_ORDER_WIDTH  ) ,
        .ADDR_WIDTH                 (`PROTOCOL_ADDR_WIDTH   ) ,
        .DATA_WIDTH                 (`PROTOCOL_DATA_WIDTH   )
        )
    inst_AHB_master(
        .clk                        (NP_clk_312M        ) ,
        .rst_n                      ( (!reset)          ) ,
        // rx channel async FIFO
        .rx_rd_en                   (rx_rd_en           ) ,
        .rx_rd_order                (rx_rd_order        ) ,
        .rx_rd_frame_start          (rx_rd_addr[33]     ) ,
        .rx_rd_action_wr            (rx_rd_addr[32]     ) ,
        .rx_rd_addr                 (rx_rd_addr[31:0]   ) ,
        .rx_rd_data                 (rx_rd_data         ) ,
        .rx_rd_empty                (rx_rd_empty        ) ,
        // AHB interface
        .AHB_haddr_m                (AHB_haddr_m        ) ,
        .AHB_hwdata_m               (AHB_hwdata_m       ) ,
        .AHB_hwrite_m               (AHB_hwrite_m       ) ,
        .AHB_hsize_m                (AHB_hsize_m        ) ,
        .AHB_hburst_m               (AHB_hburst_m       ) ,
        .AHB_htrans_m               (AHB_htrans_m       ) ,
        .AHB_hmaster_m              (AHB_hmaster_m      ) ,
        .AHB_hnonsec_m              (AHB_hnonsec_m      ) ,
        .AHB_hexcl_m                (AHB_hexcl_m        ) ,
        .AHB_hmasterlock_m          (AHB_hmasterlock_m  ) ,
        .AHB_hprot_m                (AHB_hprot_m        ) ,
        .AHB_hrdata_m               (AHB_hrdata_m       ) ,
        .AHB_hready_m               (AHB_hready_m       ) ,
        .AHB_hresp_m                (AHB_hresp_m        ) ,
        .AHB_hexokay_m              (1'b1               ) ,
        // tx channel
        .tx_wr_en                   (tx_wr_en           ) ,
        .tx_wr_order                (tx_wr_order        ) ,
        .tx_wr_frame_start          (tx_wr_addr[33]     ) ,
        .tx_wr_action_wr            (tx_wr_addr[32]     ) ,
        .tx_wr_addr                 (tx_wr_addr[31:0]   ) ,
        .tx_wr_data                 (tx_wr_data         ) ,
        .tx_wr_full                 (tx_wr_full         )
    ) ;
    // AHB assign

endmodule
